using System.Collections;

using LocalBoard.Domain;
using LocalBoard.Persistence;

using NUnit.Framework;

namespace LocalBoard.Controller
{
	[TestFixture]
	public class TestBoardController
	{
		private int _boardId;
		private int _clubId;
		private BoardController _unitUnderTest;
		private Profile _user;
		private int _boardId2;
		private int _clubId2;
		private BoardController _unitUnderTest2;
		private Profile _user2;
		MockAccessorFactory accessorFactory = new MockAccessorFactory();

		[SetUp]
		public void setUp()
		{
			IProfileAccessor profileAccessor = accessorFactory.GetProfileAccessor();
			IClubAccessor clubAccessor = accessorFactory.GetClubAccessor();
			IClubProfileAccessor clubProfileAccessor = accessorFactory.GetClubProfileAccessor();

			_clubId = clubAccessor.Insert(new Club("test", "test", 1, "test", "", null));
			ClubController clubController = new ClubController(_clubId, accessorFactory);
			_boardId = clubController.CreateBoard(new Board("test board", null, 0, 0, _clubId, BoardViewType.List));
			_unitUnderTest = new BoardController(_boardId, clubController, 1, accessorFactory);
			_user = profileAccessor.Get(profileAccessor.Insert(new Profile("userId 1", "userName 1", "password", "test@test.com")));
			clubController.AddUserClubProfile(null, _user.Id);
			_clubId2 = clubAccessor.Insert(new Club("test2", "test2", 1, "test2", "", null));
			ClubController clubController2 = new ClubController(_clubId2, accessorFactory);
			_boardId2 = clubController.CreateBoard(new Board("test board2", null, 0, 0, _clubId2, BoardViewType.List));
			_unitUnderTest2 = new BoardController(_boardId2, clubController2, 1, accessorFactory);
			_user2 = profileAccessor.Get(profileAccessor.Insert(new Profile("userId 2", "userName 2", "password", "test@test.com")));
			clubController2.AddUserClubProfile(null, _user2.Id);
		}

		[TearDown]
		public void tearDown()
		{
			MockAccessorFactory.ResetDataTable();
			_unitUnderTest = null;
			_unitUnderTest2 = null;
		}

		[Test]
		public void testPostMessage()
		{
			int messageId = _unitUnderTest.PostMessage("subject 1", "body 1", _user, 0);
			Message message = _unitUnderTest.GetMessage(messageId);

			Assert.IsNotNull(message);
			Assert.AreEqual("body 1", message.Body);

			int messageId2 = _unitUnderTest2.PostMessage("subject 2", "body 2", _user2, 0);
			Message message2 = _unitUnderTest2.GetMessage(messageId2);

			Assert.IsNotNull(message2);
			Assert.AreEqual("body 2", message2.Body);
		}

//		[Test]
//		public void testPostMessage2()
//		{
//			int messageId = _unitUnderTest.PostMessage("subject 1", "body 1", _user, 0, _unitUnderTest.BoardId);
//			Message message = _unitUnderTest.GetMessage(messageId);
//
//			Assert.IsNotNull(message);
//			Assert.AreEqual("body 1", message.Body);
//
//			int messageId2 = _unitUnderTest2.PostMessage("subject 2", "body 2", _user2, 0, _unitUnderTest2.BoardId);
//			Message message2 = _unitUnderTest2.GetMessage(messageId2);
//
//			Assert.IsNotNull(message2);
//			Assert.AreEqual("body 2", message2.Body);
//		}

		[Test]
		public void testUpdateMessage()
		{
			int messageId = _unitUnderTest.PostMessage("subject 2", "body 2", _user, 0);
			_unitUnderTest.EditMessage(_unitUnderTest.GetMessage(messageId), "subject 2 changed", "body 2 changed");

			Message message = _unitUnderTest.GetMessage(messageId);
			Assert.IsNotNull(message);
			Assert.AreEqual("subject 2 changed", message.Subject);
			Assert.AreEqual("body 2 changed", message.Body);

			int messageId2 = _unitUnderTest2.PostMessage("subject 1", "body 1", _user, 0);
			_unitUnderTest2.EditMessage(_unitUnderTest2.GetMessage(messageId2), "subject 1 changed", "body 1 changed");

			Message message2 = _unitUnderTest2.GetMessage(messageId2);
			Assert.IsNotNull(message2);
			Assert.AreEqual("subject 1 changed", message2.Subject);
			Assert.AreEqual("body 1 changed", message2.Body);
		}

		[Test]
		public void testDeleteMessage()
		{
			int messageId = _unitUnderTest.PostMessage("subject 3", "body 3", _user, 0);
			_unitUnderTest.DeleteMessage(messageId);

			Assert.IsNull(_unitUnderTest.GetMessage(messageId));
		}

		[Test]
		public void testGetMessageListForPage()
		{
			int messageId1 = _unitUnderTest.PostMessage("subject 4", "body 4", _user, 0);
			int messageId2 = _unitUnderTest.PostMessage("subject 5", "body 5", _user, 0);

			ArrayList messageList = _unitUnderTest.GetMessageListForCurrentPage();

			Message msg1 = _unitUnderTest.GetMessage(messageId1);
			Message msg2 = _unitUnderTest.GetMessage(messageId2);

			bool foundMsg1 = false, foundMsg2 = false;
			foreach(Message message in messageList)
			{
				if(message.Body == msg1.Body)
					foundMsg1 = true;
				else if(message.Subject == msg2.Subject)
					foundMsg2 = true;
			}

			Assert.IsTrue(foundMsg1 && foundMsg2);
		}

		[Test]
		public void testIncreaseHits()
		{
			Profile anonymousUser = accessorFactory.GetProfileAccessor().GetAnonymousUser();
			int messageId = _unitUnderTest.PostMessage("subject 1", "body 1", anonymousUser, 0);
			Message message = _unitUnderTest.GetMessage(messageId);
			_unitUnderTest.IncreaseHits(anonymousUser, ref message);
			Assert.AreEqual(1, message.Hits);
			message = _unitUnderTest.GetMessage(messageId);
			Assert.AreEqual(1, message.Hits);
			_unitUnderTest.IncreaseHits(_user, ref message);
			message = _unitUnderTest.GetMessage(messageId);
			Assert.AreEqual(2, message.Hits);

			int messageId2 = _unitUnderTest.PostMessage("subject 2", "body 2", _user, 0);
			Message message2 = _unitUnderTest.GetMessage(messageId2);
			_unitUnderTest.IncreaseHits(anonymousUser, ref message2);
			Assert.AreEqual(1, message2.Hits);
			message2 = _unitUnderTest.GetMessage(messageId2);
			Assert.AreEqual(1, message2.Hits);
			_unitUnderTest.IncreaseHits(_user, ref message2);
			message2 = _unitUnderTest.GetMessage(messageId2);
			Assert.AreEqual(1, message2.Hits);
		}
		[Test]
		public void testRateMessage()
		{
			int messageId = _unitUnderTest.PostMessage("subject 2", "body 2", _user, 0);
			Message message = _unitUnderTest.GetMessage(messageId);
			_unitUnderTest.RateMessage(message.Id, _user.Id, 4);
			_unitUnderTest.RateMessage(message.Id, _user2.Id, 5);
			Assert.AreEqual(2, _unitUnderTest.GetRateListByMessageId(message.Id).Count);
			foreach(Vote vote in _unitUnderTest.GetRateListByMessageId(message.Id))
			{
				if(vote.ProfileId == _user.Id)
					Assert.AreEqual(4, vote.Point);
				if(vote.ProfileId == _user2.Id)
					Assert.AreEqual(5, vote.Point);
			}
		}
		[Test]
		public void testGetBoardSecurity()
		{
			BoardSecurity returnVal = _unitUnderTest.GetBoardSecurity();

			Assert.IsNotNull(returnVal);
		}
//		[Test]
//		public void testGetBoardSecurity2()
//		{
//			BoardSecurity returnVal = _unitUnderTest.GetBoardSecurity(_unitUnderTest.BoardId);
//
//			Assert.IsNotNull(returnVal);
//		}
	}
}